package com.letv.core.network.volley;

import com.letv.core.bean.LetvBaseBean;
import com.letv.core.network.volley.VolleyResponse.CacheResponseState;
import com.letv.core.network.volley.VolleyResponse.ResponseSupplier;
import com.letv.core.network.volley.VolleyResult.VolleyCacheResult;
import com.letv.core.network.volley.listener.ResponseDelivery;
import com.letv.core.network.volley.listener.VolleyCache;
import com.letv.core.network.volley.toolbox.VolleyDbCache;
import com.letv.core.network.volley.toolbox.VolleyDiskCache;
import com.letv.core.network.volley.toolbox.VolleyNoCache;

/**
 * 缓存请求数据
 * 
 * @author zhuqiao
 *
 */
public class CacheRequestData<T extends LetvBaseBean> extends BaseRequestData<T> {
    /** 是否同步.如果是true,那么需要从回调中拿数据;else,直接返回数据 **/
    private final boolean mIsSync;

    public CacheRequestData(ResponseDelivery delivery, boolean isSync) {
        super(ResponseSupplier.CACHE, delivery);
        mIsSync = isSync;
    }

    /**
     * 开始请求
     * 
     * @param request
     * @return
     */
    public VolleyCacheResult<T> start(VolleyRequest<T> request) {
        if (isCanceled(request)) {
            return mIsSync ? new VolleyCacheResult<T>(null, request.mCacheDataHull, CacheResponseState.IGNORE) : null;
        }

        if (!isValidateSuccess(request)) {
            return mIsSync ? new VolleyCacheResult<T>(null, request.mCacheDataHull, CacheResponseState.ERROR) : null;
        }

        // 从缓存中获取数据
        VolleyResponse response = fetchResponseFromCache(request);

        if (!isResponseAvailabe(request, response)) {
            if (mIsSync) {
                return new VolleyCacheResult<T>(null, request.mCacheDataHull, CacheResponseState.ERROR);
            }

            postError(request, CacheResponseState.ERROR);
            return null;
        }

        return parseResponse(request, response);
    }

    /**
     * 从缓存中获取response
     * 
     * @param request
     * @return
     */
    private VolleyResponse fetchResponseFromCache(VolleyRequest<?> request) {
        if (request == null || request.getVolleyCache() == null) {
            return new VolleyResponse(ResponseSupplier.CACHE);
        }

        VolleyCache<?> cache = request.getVolleyCache();

        if (cache instanceof VolleyNoCache) {
            return new VolleyResponse(ResponseSupplier.CACHE);
        } else if (cache instanceof VolleyDiskCache) {
            return new VolleyResponse(((VolleyDiskCache) cache).get(request), ResponseSupplier.CACHE);
        } else if (cache instanceof VolleyDbCache) {
            Object result = cache.get(request);
            if (result instanceof LetvBaseBean) {
                return new VolleyResponse((LetvBaseBean) result, ResponseSupplier.CACHE);
            }
        }

        return new VolleyResponse(ResponseSupplier.CACHE);
    }

    /**
     * 解析response
     * 
     * @param request
     * @param response
     */
    private VolleyCacheResult<T> parseResponse(VolleyRequest<T> request, VolleyResponse response) {
        if (request.getVolleyCache() instanceof VolleyDbCache) {
            // 数据库缓存
            return checkDbCache(request, response);
        } else if (request.getVolleyCache() instanceof VolleyDiskCache) {
            // 文件缓存
            return checkDiskCache(request, response);
        } else {
            // 无缓存
            if (mIsSync) {
                return new VolleyCacheResult<T>(null, request.mCacheDataHull, CacheResponseState.ERROR);
            }

            postError(request, CacheResponseState.ERROR);
            return null;
        }
    }

    /**
     * 验证数据库缓存
     * 
     * @param request
     * @param response
     */
    private VolleyCacheResult<T> checkDbCache(VolleyRequest<T> request, VolleyResponse response) {
        if (response.entry instanceof LetvBaseBean) {
            request.setCacheEntry(response.entry);
            request.setCacheSuccess();

            if (mIsSync) {
                return new VolleyCacheResult<T>(request.getCacheEntry(), request.mCacheDataHull,
                        CacheResponseState.SUCCESS);
            }

            postResponse(request);
        } else {
            if (mIsSync) {
                return new VolleyCacheResult<T>(null, request.mCacheDataHull, CacheResponseState.ERROR);
            }

            postError(request, CacheResponseState.ERROR);
        }

        return null;
    }

    /**
     * 验证文件缓存
     * 
     * @param request
     * @param response
     */
    private VolleyCacheResult<T> checkDiskCache(VolleyRequest<T> request, VolleyResponse response) {
        try {
            request.parse(response, ResponseSupplier.CACHE);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (request.getCacheEntry() instanceof LetvBaseBean) {
            request.setCacheSuccess();
            request.mCacheDataHull.setSourceData(response.data);
            request.mCacheDataHull.setMarkId(request.getMarkId());

            if (mIsSync) {
                return new VolleyCacheResult<T>(request.getCacheEntry(), request.mCacheDataHull,
                        CacheResponseState.SUCCESS);
            }

            postResponse(request);
        } else {
            if (mIsSync) {
                return new VolleyCacheResult<T>(null, request.mCacheDataHull, CacheResponseState.ERROR);
            }

            postError(request, CacheResponseState.ERROR);
        }

        return null;
    }
}
